home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-14 | 39.6 KB | 1,286 lines |
- Newsgroups: comp.sources.misc
- X-UNIX-From: dvadura@watdragon.waterloo.edu
- subject: v15i072: dmake version 3.6 (part 20/25)
- from: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 15, Issue 72
- Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Archive-name: dmake-3.6/part20
-
- #!/bin/sh
- # this is part 20 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file infer.c continued
- #
- CurArch=20
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file infer.c"
- sed 's/^X//' << 'SHAR_EOF' >> infer.c
- X * and we should Define it and attach it to the CELL pointed at
- X * by cp. This recursive inference is performed only if
- X * Transitive closure is enabled.
- X */
- X if( _trans ) {
- X int _save = _dmax;
- X if( !_dmax ) _dmax += _dmax_fix;
- X infcell = Infer_recipe( &iprq, iprq.CE_HOW, &top_dfa_stack,
- X sdir);
- X _dmax = _save;
- X
- X if( infcell != NIL(CELL) ) {
- X /* We found we can make the prerequisite, so make it into
- X * a real node. This means, mark it for possible
- X * removal, and when you make it into a node make sure
- X * you don't clobber the Def_cell name.
- X */
- X infcell = Def_cell( iprqh.ht_name, setdirroot );
- X thp = infcell->ce_name;
- X *infcell = iprq;
- X infcell->ce_name = thp;
- X infcell->ce_flag |= F_REMOVE;
- X }
- X }
- X
- X /* If we pushed a directory for the inferred prerequisite then
- X * pop it.
- X */
- X if( ipush ) Pop_dir(FALSE);
- X
- Xtry_next_edge:
- X FREE( iprqh.ht_name );
- X }
- X
- X edge = edge->ed_next;
- X }
- X while( infcell == NIL(CELL) && edge != meta->CE_EDGES );
- X
- X
- X /* If none of the previous edges were any good, and there was an
- X * edge with no prerequsite, then use it.
- X */
- X if( infcell == NIL(CELL) )
- X if( edge_noprq != NIL(EDGE) )
- X pedge = edge_noprq;
- X else
- X pedge = NIL(EDGE);
- X else {
- X /* We have a match, so make the edge's pointer for the corresponding
- X * %-meta target point at the matched prerequisite so that the next
- X * time we perform an inference we will check this edge first.
- X */
- X meta->CE_EDGES = pedge;
- X if( !_trans ) infcell->ce_attr |= A_NOINFER;
- X }
- X
- X
- X /* If we pushed a dir when we treated this %-meta, then
- X * pop it.
- X */
- X if( push ) Pop_dir(FALSE);
- X
- X
- X /* Need this so that pdfa does not get advanced, and remains pointing
- X * to the dfa, that just resulted in a successful match.
- X */
- X if( pedge != NIL(EDGE) ) break;
- X }
- X
- X
- X /* If pedge is not NIL then we have found an edge and possibly inferred
- X * a prerequisite. In any case we should definitely attach the recipe to
- X * the HOW node of the cell pointed at by cp. If the CELL has no HOW node
- X * the we allocate one.
- X */
- X if( pedge != NIL(EDGE) ) {
- X LINKPTR lp;
- X HOWPTR nhow, ihow;
- X
- X DB_PRINT("inf", ("taking edge [%s] to [%s]", pedge->ed_tg->CE_NAME,
- X (pedge->ed_prq == NIL(CELL)) ? "(none)":pedge->ed_prq->CE_NAME));
- X
- X if( Verbose )
- X printf("%s: Inferred recipe using edge from [%s] to [%s]\n",
- X Pname, pedge->ed_tg->CE_NAME,
- X (pedge->ed_prq == NIL(CELL)) ? "(none)":pedge->ed_prq->CE_NAME);
- X
- X if( how == NIL(HOW) ) {
- X /* Get a new HOW node, this should happen only for inferred
- X * cells, as such they have no prior HOW node */
- X TALLOC( how, 1, HOW );
- X cp->CE_HOW = how;
- X }
- X
- X
- X /* Attach the recipe to the HOW node. Note that if the %-meta recipe
- X * is a :: recipe then we will attach all of the HOW cells belonging to
- X * the %-meta :: rule that we matched to the CELL, and we will place
- X * them so that they preceed subsequent HOW cells in the list. Under
- X * these circumstances the CELL is marked as a MULTI cell.
- X */
- X nhow = how->hw_next;
- X for( ihow=meta->CE_EDGES->ed_how; ihow != NIL(HOW); ihow=ihow->hw_next ) {
- X how->hw_per = pdfa->dl_per;
- X how->hw_flag |= (ihow->hw_flag & (F_SINGLE | F_GROUP)) | F_INFER;
- X how->hw_attr |= (ihow->hw_attr & A_TRANSFER);
- X how->hw_recipe = ihow->hw_recipe;
- X
- X /* Add global prerequisites to the first HOW cell
- X */
- X for( lp=ihow->hw_indprq; lp != NIL(LINK); lp=lp->cl_next ) {
- X char *name = lp->cl_prq->CE_NAME;
- X CELLPTR tcp;
- X
- X name = _build_name( cp->CE_NAME, name, pdfa->dl_per );
- X tcp = Def_cell( name, setdirroot );
- X tcp->ce_flag |= F_REMOVE;
- X Add_prerequisite( how, tcp, FALSE );
- X
- X if( Verbose )
- X printf( "%s: Inferred indirect prerequisite [%s]\n",
- X Pname, name );
- X FREE(name);
- X }
- X
- X /* If infcell is not NIL then we have inferred a prerequisite, so
- X * add it to the first HOW cell as well.
- X */
- X if( infcell != NIL(CELL) ) {
- X (Add_prerequisite( how, infcell, FALSE))->cl_flag |= F_TARGET;
- X
- X if( Verbose )
- X printf( "%s: Inferred prerequisite [%s]\n",
- X Pname, infcell->CE_NAME );
- X }
- X
- X /* If the recipe is a :: recipe then Insert a new HOW node after
- X * the inferred recipe HOW node and prior to any previous
- X * :: nodes.
- X */
- X if( ihow->hw_next != NIL(HOW) ) {
- X cp->ce_flag |= F_MULTI;
- X TALLOC( how->hw_next, 1, HOW );
- X how = how->hw_next;
- X }
- X }
- X how->hw_next = nhow;
- X pdfa->dl_per = NIL(char); /* We used it, so don't FREE it */
- X
- X /* Make sure to set the FLAGS, and ATTRIBUTES of the CELL so that it
- X * gets made correctly.
- X */
- X cp->ce_flag |= F_RULES | F_TARGET | F_INFER;
- X
- X if( !(cp->ce_attr & A_SETDIR) ) {
- X cp->ce_attr |= (meta->ce_attr & A_SETDIR);
- X cp->ce_dir = meta->ce_dir;
- X }
- X }
- X else
- X cp = NIL(CELL);
- X
- X _free_dfas( dfas );
- X
- X DB_PRINT( "mem", ("%s:-< mem %ld", (cp!=NIL(CELL)) ? cp->CE_NAME : "(none)",
- X (long)coreleft()));
- X DB_PRINT( "inf", ("<<< Exit, cp = %04x", cp) );
- X DB_RETURN( cp );
- X}
- X
- X
- Xstatic char *
- X_build_name( tg, meta, per )
- Xchar *tg;
- Xchar *meta;
- Xchar *per;
- X{
- X char *name;
- X
- X name = Apply_edit( meta, "%", per, FALSE, FALSE );
- X if( strchr(name, '$') ) {
- X HASHPTR m_at;
- X char *tmp;
- X
- X m_at = Def_macro( "@", tg, M_MULTI );
- X tmp = Expand( name );
- X
- X if( m_at->ht_value != NIL(char) ) {
- X FREE( m_at->ht_value );
- X m_at->ht_value = NIL(char);
- X }
- X
- X if( name != meta ) FREE( name );
- X name = tmp;
- X }
- X else if( name == meta )
- X name = _strdup( name );
- X
- X return(name);
- X}
- X
- X
- Xstatic DFALINKPTR
- X_dfa_subset( pdfa, stack )/*
- X============================
- X This is the valid DFA subset computation. Whenever a CELL has a Match_dfa
- X subset computed this algorithm is run to see if any of the previously
- X computed sets on the DFA stack are proper subsets of the new set. If they
- X are, then any elements of the matching subset whose Prep counts exceed
- X the allowed maximum given by Prep are removed from the computed DFA set,
- X and hence from consideration, thereby cutting off the cycle in the
- X inference graph. */
- XDFALINKPTR pdfa;
- Xregister DFASETPTR stack;
- X{
- X register DFALINKPTR element;
- X DFALINKPTR nelement;
- X
- X DB_ENTER( "_dfa_subset" );
- X
- X for(; pdfa != NIL(DFALINK) && stack != NIL(DFASET); stack = stack->df_next) {
- X int subset = TRUE;
- X
- X for( element=stack->df_set; subset && element != NIL(DFALINK);
- X element=element->dl_next ) {
- X register DFALINKPTR subel;
- X
- X for( subel = pdfa;
- X subel != NIL(DFALINK) && (subel->dl_meta != element->dl_meta);
- X subel = subel->dl_next );
- X
- X if( subset = (subel != NIL(DFALINK)) ) element->dl_member = subel;
- X }
- X
- X if( subset )
- X for( element=stack->df_set; element != NIL(DFALINK);
- X element=element->dl_next ) {
- X DFALINKPTR mem = element->dl_member;
- X int npr = element->dl_prep + 1;
- X
- X if( npr > _prep )
- X mem->dl_delete++;
- X else
- X mem->dl_prep = npr;
- X }
- X }
- X
- X for( element = pdfa; element != NIL(DFALINK); element = nelement ) {
- X nelement = element->dl_next;
- X
- X if( element->dl_delete ) {
- X /* A member of the subset has a PREP count equal to PREP, so
- X * it should not be considered further in the inference, hence
- X * we remove it from the doubly linked set list */
- X if( element == pdfa )
- X pdfa = element->dl_next;
- X else
- X element->dl_prev->dl_next = element->dl_next;
- X
- X if( element->dl_next != NIL(DFALINK) )
- X element->dl_next->dl_prev = element->dl_prev;
- X
- X DB_PRINT("inf", ("deleting dfa [%s]", element->dl_meta->CE_NAME));
- X FREE( element->dl_per );
- X FREE( element );
- X }
- X }
- X
- X DB_RETURN( pdfa );
- X}
- X
- X
- X
- Xstatic void
- X_free_dfas( chain )/*
- X=====================
- X Free the list of DFA's constructed by Match_dfa, and linked together by
- X LINK cells. FREE the % value as well, as long as it isn't NIL. */
- XDFALINKPTR chain;
- X{
- X register DFALINKPTR tl;
- X
- X DB_ENTER( "_free_dfas" );
- X
- X for( tl=chain; tl != NIL(DFALINK); chain = tl ) {
- X tl = tl->dl_next;
- X
- X DB_PRINT( "inf", ("Freeing DFA [%s], %% = [%s]", chain->dl_meta->CE_NAME,
- X chain->dl_per) );
- X
- X if( chain->dl_per != NIL(char) ) FREE( chain->dl_per );
- X FREE( chain );
- X }
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- Xstatic int
- X_count_dots( name )/*
- X=====================*/
- Xchar *name;
- X{
- X register char *p;
- X register int i = 0;
- X
- X for( p = name; *p; p++ ) if(*p == '.') i++;
- X
- X return( i );
- X}
- SHAR_EOF
- echo "File infer.c is complete"
- chmod 0440 infer.c || echo "restore of infer.c fails"
- echo "x - extracting imacs.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > imacs.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/imacs.c,v 1.1 90/10/06 12:03:48 dvadura Exp $
- X-- SYNOPSIS -- define default internal macros.
- X--
- X-- DESCRIPTION
- X-- This file adds to the internal macro tables the set of default
- X-- internal macros, and for those that are accessible internally via
- X-- variables creates these variables, and initializes them to point
- X-- at the default values of these macros.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: imacs.c,v $
- X * Revision 1.1 90/10/06 12:03:48 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#include "extern.h"
- X
- Xstatic void _set_int_var ANSI((char *, char *, int, int *));
- Xstatic void _set_string_var ANSI((char *, char *, int, char **));
- Xstatic void _set_bit_var ANSI((char *, char *, int));
- X
- X/*
- X** Arrange to parse the strings stored in Rules[]
- X*/
- Xvoid
- XMake_rules()
- X{
- X Parse(NIL(FILE));
- X}
- X
- X
- X#define M_FLAG M_DEFAULT | M_EXPANDED
- X
- X/*
- X** Add to the macro table all of the internal macro variables plus
- X** create secondary variables which will give access to their values
- X** easily, both when needed and when the macro value is modified.
- X** The latter is accomplished by providing a flag in the macro and a field
- X** which gives a pointer to the value if it is a char or string macro value
- X** and a mask representing the bit of the global flag register that is affected
- X** by this macro's value.
- X*/
- Xvoid
- XCreate_macro_vars()
- X{
- X static char* switchar;
- X char swchar[2];
- X
- X swchar[0] = Get_switch_char(), swchar[1] = '\0';
- X _set_string_var("SWITCHAR", swchar, M_PRECIOUS, &switchar);
- X _set_string_var("DIRSEPSTR", "/", M_PRECIOUS, &DirSepStr);
- X _set_string_var("DIRBRKSTR", DirBrkStr, M_PRECIOUS, &DirBrkStr);
- X
- X _set_bit_var(".SILENT", "", A_SILENT );
- X _set_bit_var(".IGNORE", "", A_IGNORE );
- X _set_bit_var(".PRECIOUS", "", A_PRECIOUS);
- X _set_bit_var(".EPILOG", "", A_EPILOG );
- X _set_bit_var(".PROLOG", "", A_PROLOG );
- X _set_bit_var(".NOINFER", "", A_NOINFER );
- X _set_bit_var(".SEQUENTIAL","",A_SEQ );
- X _set_bit_var(".USESHELL", "", A_SHELL );
- X _set_bit_var(".SWAP", "", A_SWAP );
- X _set_bit_var(".MKSARGS", "", A_MKSARGS );
- X
- X Glob_attr = A_DEFAULT; /* set all flags to NULL */
- X
- X _set_string_var("SHELL", "", M_DEFAULT, &Shell );
- X _set_string_var("SHELLFLAGS", " ", M_DEFAULT, &Shell_flags );
- X _set_string_var("GROUPSHELL", "", M_DEFAULT, &GShell );
- X _set_string_var("GROUPFLAGS", " ", M_DEFAULT, &GShell_flags);
- X _set_string_var("SHELLMETAS", "", M_DEFAULT, &Shell_metas );
- X _set_string_var("GROUPSUFFIX", "", M_DEFAULT, &Grp_suff );
- X _set_string_var("PREP", "0", M_DEFAULT, &Prep );
- X _set_string_var("AUGMAKE",NIL(char), M_DEFAULT, &Augmake );
- X
- X _set_string_var("MAKEDIR", Get_current_dir(), M_PRECIOUS|M_NOEXPORT,
- X &Makedir);
- X _set_string_var("PWD", Makedir, M_DEFAULT|M_NOEXPORT, &Pwd);
- X
- X Def_macro("NULL", "", M_PRECIOUS|M_NOEXPORT|M_FLAG);
- X
- X _set_int_var( "MAXLINELENGTH", "0", M_DEFAULT|M_NOEXPORT, &Buffer_size );
- X (void) Def_macro("MAXLINELENGTH", "0", M_FLAG | M_DEFAULT);
- X
- X /* set MAXPROCESSLIMIT high initially so that it allows MAXPROCESS to
- X * change from command line. */
- X _set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT, &Max_proclmt );
- X _set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc );
- X}
- X
- X/*
- X** Define a string variable value, and set up the macro.
- X*/
- Xstatic void
- X_set_int_var(name, val, flag, var)
- Xchar *name;
- Xchar *val;
- Xint flag;
- Xint *var;
- X{
- X HASHPTR hp;
- X
- X hp = Def_macro(name, val, M_FLAG | flag);
- X hp->ht_flag |= M_VAR_INT | M_MULTI;
- X hp->MV_IVAR = var;
- X *var = atoi(val);
- X}
- X
- X/*
- X** Define a string variables value, and set up the macro.
- X*/
- Xstatic void
- X_set_string_var(name, val, flag, var)
- Xchar *name;
- Xchar *val;
- Xint flag;
- Xchar **var;
- X{
- X HASHPTR hp;
- X
- X hp = Def_macro(name, val, M_FLAG | flag);
- X hp->ht_flag |= M_VAR_STRING | M_MULTI;
- X hp->MV_SVAR = var;
- X *var = hp->ht_value;
- X}
- X
- X/*
- X** Define a string variables value, and set up the macro.
- X*/
- Xstatic void
- X_set_bit_var(name, val, mask)
- Xchar *name;
- Xchar *val;
- Xint mask;
- X{
- X HASHPTR hp;
- X
- X hp = Def_macro(name, val, M_FLAG);
- X hp->ht_flag |= M_VAR_BIT | M_MULTI;
- X hp->MV_MASK = mask;
- X hp->MV_BVAR = &Glob_attr;
- X}
- SHAR_EOF
- chmod 0440 imacs.c || echo "restore of imacs.c fails"
- echo "x - extracting hash.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > hash.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/hash.c,v 1.1 90/10/06 12:03:45 dvadura Exp $
- X-- SYNOPSIS -- hashing function for hash tables.
- X--
- X-- DESCRIPTION
- X-- Hash an identifier. The hashing function works by computing the sum
- X-- of each char and the previous hash value multiplied by 129. Finally the
- X-- length of the identifier is added in. This way the hash depends on the
- X-- chars as well as the length, and appears to be sufficiently unique,
- X-- and is FAST to COMPUTE, unlike the previous hash function...
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: hash.c,v $
- X * Revision 1.1 90/10/06 12:03:45 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#include "extern.h"
- X
- Xuint16
- XHash( id, phv )/*
- X=================
- X This function computes the identifier's hash value and returns the hash
- X value modulo the key size as well as the full hash value. The reason
- X for returning both is so that hash table searches can be sped up. You
- X compare hash keys instead and compare strings only for those whose 32-bit
- X hash keys match. (not many) */
- X
- Xchar *id;
- Xuint32 *phv;
- X{
- X register char *p = id;
- X register uint32 hash = (uint32) 0;
- X
- X while( *p ) hash = (hash << 7) + hash + (uint32) (*p++);
- X *phv = hash = hash + (uint32) (p-id);
- X
- X return( (uint16) (hash % HASH_TABLE_SIZE) );
- X}
- X
- SHAR_EOF
- chmod 0440 hash.c || echo "restore of hash.c fails"
- echo "x - extracting getinp.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > getinp.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/getinp.c,v 1.1 90/10/06 12:03:43 dvadura Exp $
- X-- SYNOPSIS -- handle reading of input.
- X--
- X-- DESCRIPTION
- X-- The code in this file reads the input from the specified stream
- X-- into the provided buffer of size Buffer_size. In doing so it deletes
- X-- comments. Comments are delimited by the #, and
- X-- <nl> character sequences. An exception is \# which
- X-- is replaced by # in the input. Line continuations are signalled
- X-- at the end of a line and are recognized inside comments.
- X-- The line continuation is always <\><nl>.
- X--
- X-- If the file to read is NIL(FILE) then the Get_line routine returns the
- X-- next rule from the builtin rule table if there is one.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: getinp.c,v $
- X * Revision 1.1 90/10/06 12:03:43 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#include "extern.h"
- X#include "alloc.h"
- X#include "db.h"
- X
- X#define IS_WHITE(A) ((A == ' ') || (A == '\t') || (A == '\n'))
- X#define SCAN_WHITE(A) \
- X while( IS_WHITE(*A) ) A++;
- X
- Xstatic int _is_conditional ANSI((char*));
- Xstatic int _handle_conditional ANSI((int, TKSTRPTR));
- X
- Xstatic int rule_ind = 0; /* index of rule when reading Rule_tab */
- Xstatic int skip = FALSE; /* if true the skip input */
- X
- X
- Xint
- XGet_line( buf, fil )/*
- X======================
- X Read a line of input from the file stripping
- X off comments. The routine returns TRUE if EOF */
- Xchar *buf;
- XFILE *fil;
- X{
- X extern char **Rule_tab;
- X register char *p;
- X register char *q;
- X register char *c;
- X char *buf_org;
- X static int ignore = FALSE;
- X int cont = FALSE;
- X int pos = 0;
- X int res;
- X
- X DB_ENTER( "Get_line" );
- X
- X if( fil == NIL(FILE) ) {
- X /* Reading the internal rule table. Set the rule_index to zero.
- X * This way ReadEnvironment works as expected every time. */
- X
- X while( (p = Rule_tab[ rule_ind++ ]) != NIL(char) )
- X /* The last test in this if '*p != '~', handles the environment
- X * passing conventions used by MKS to pass arguments. We want to
- X * skip those environment entries. */
- X if( !Readenv || (Readenv && (strchr(p,'=') != NIL(char)) && *p!='~')){
- X strcpy( buf, p );
- X
- X DB_PRINT( "io", ("Returning [%s]", buf) );
- X DB_RETURN( FALSE );
- X }
- X
- X rule_ind = 0;
- X
- X DB_PRINT( "io", ("Done Ruletab") );
- X DB_RETURN( TRUE );
- X }
- X
- X buf_org = buf;
- X
- Xdo_again:
- X do {
- X p = buf+pos;
- X if(feof( fil ) || (fgets( p, Buffer_size-pos, fil ) == NIL(char)))
- X DB_RETURN( TRUE );
- X
- X Line_number++;
- X
- X /* ignore input if ignore flag set and line ends in a continuation
- X character. */
- X
- X q = p+strlen(p)-2;
- X if( ignore ) {
- X if( q[0] != CONTINUATION_CHAR || q[1] != '\n' ) ignore = FALSE;
- X *p = '\0';
- X continue;
- X }
- X
- X /* Search the input string looking for comment chars. If it contains
- X * comment chars then NUKE the remainder of the line, if the comment
- X * char is preceeded by \ then shift the remainder of the line left
- X * by one char. */
- X
- X c = p;
- X
- X while( (c = strchr(c, COMMENT_CHAR)) != NIL(char) ) {
- X if( c != p && c[-1] == ESCAPE_CHAR ) {
- X strcpy( c-1, c ); /* copy it left, due to \# */
- X q--; /* shift tail pointer left */
- X }
- X else {
- X *c = '\0'; /* a true comment so break */
- X break;
- X }
- X }
- X
- X /* Does the end of the line end in a continuation sequence? */
- X
- X if( (q[0] == CONTINUATION_CHAR) && (q[1] == '\n')) {
- X /* If the continuation was at the end of a comment then ignore the
- X * next input line, (or lines until we get one ending in just <nl>)
- X * else it's a continuation, so build the input line from several
- X * text lines on input. The maximum size of this is governened by
- X * Buffer_size */
- X if( q != p && q[-1] == CONTINUATION_CHAR ) {
- X strcpy( q, q+1 );
- X q--;
- X cont = FALSE;
- X }
- X else if( c != NIL(char) )
- X ignore = TRUE;
- X else
- X cont = TRUE;
- X }
- X else {
- X cont = FALSE;
- X }
- X
- X q = ( c == NIL(char) ) ? q+2 : c;
- X pos += q-p;
- X }
- X while( (cont || !*buf) && (pos <= Buffer_size) );
- X
- X if( buf[ pos-1 ] == '\n' )
- X buf[ --pos ] = '\0';
- X else
- X if( pos == Buffer_size-1 )
- X Fatal( "Input line too long, increase MAXLINELENGTH" );
- X
- X
- X /* Now that we have the next line of input to make, we should check to
- X * see if it is a conditional expression. If it is then process it,
- X * otherwise pass it on to the parser. */
- X
- X if( *(p = _strspn(buf, " \t")) == CONDSTART ) {
- X TKSTR token;
- X
- X SET_TOKEN( &token, p );
- X
- X p = Get_token( &token, "", FALSE );
- X
- X if( (res = _is_conditional( p )) ) /* ignore non control special */
- X { /* targets */
- X res = _handle_conditional( res, &token );
- X skip = TRUE;
- X }
- X else {
- X CLEAR_TOKEN( &token );
- X res = TRUE;
- X }
- X }
- X
- X if( skip ) {
- X buf = buf_org; /* ignore line just read in */
- X pos = 0;
- X skip = res;
- X goto do_again;
- X }
- X
- X DB_PRINT( "io", ("Returning [%s]", buf) );
- X DB_RETURN( FALSE );
- X}
- X
- X
- X
- Xchar *
- XGet_token( string, brk, anchor )/*
- X==================================
- X Return the next token in string.
- X Returns empty string when no more tokens in string.
- X brk is a list of chars that also cause breaks in addition to space and
- X tab, but are themselves returned as tokens. if brk is NULL then the
- X remainder of the line is returned as a single token.
- X
- X anchor if TRUE, says break on chars in the brk list, but only if
- X the entire token begins with the first char of the brk list, if
- X FALSE then any char of brk will cause a break to occurr. */
- X
- XTKSTRPTR string;
- Xchar *brk;
- Xint anchor;
- X{
- X register char *s;
- X register char *curp;
- X register char *t;
- X int done = FALSE;
- X char space[10];
- X
- X DB_ENTER( "Get_token" );
- X
- X s = string->tk_str; /* Get string parameters */
- X *s = string->tk_cchar; /* ... and strip leading w/s */
- X
- X SCAN_WHITE( s );
- X
- X DB_PRINT( "tok", ("What's left [%s]", s) );
- X
- X if( !*s ) {
- X DB_PRINT( "tok", ("Returning NULL token") );
- X DB_RETURN( "" );
- X }
- X
- X
- X /* Build the space list. space contains all those chars that may possibly
- X * cause breaks. This includes the brk list as well as white space. */
- X
- X if( brk != NIL(char) ) {
- X strcpy( space, " \t\n" );
- X strcat( space, brk );
- X }
- X else {
- X space[0] = 0xff; /* a char we know will not show up */
- X space[1] = 0;
- X }
- X
- X
- X /* Handle processing of quoted tokens. Note that this is disabled if
- X * brk is equal to NIL */
- X
- X while( *s == '\"' && ((brk != NIL(char)) || !string->tk_quote) ) {
- X s++;
- X if( string->tk_quote ) {
- X curp = s-1;
- X do { curp = strchr( curp+1, '\"' ); }
- X while( (curp != NIL(char)) && (*(curp+1) == '\"'));
- X
- X if( curp == NIL(char) ) Fatal( "Unmatched quote in token" );
- X string->tk_quote = !string->tk_quote;
- X
- X /* Check for "" case, and if found ignore it */
- X if( curp == s ) continue;
- X goto found_token;
- X }
- X else
- X SCAN_WHITE( s );
- X
- X string->tk_quote = !string->tk_quote;
- X }
- X
- X
- X /* Check for a token break character at the beginning of the token.
- X * If found return the next set of break chars as a token. */
- X
- X if( (brk != NIL(char)) && (strchr( brk, *s ) != NIL(char)) ) {
- X curp = _strspn( s, brk );
- X done = (anchor == 0) ? TRUE :
- X ((anchor == 1)?(*s == *brk) : (*brk == curp[-1]));
- X }
- X
- X
- X /* Scan for the next token in the list and return it less the break char
- X * that was used to terminate the token. It will possibly be returned in
- X * the next call to Get_token */
- X
- X if( !done ) {
- X SCAN_WHITE( s );
- X
- X t = s;
- X do {
- X done = TRUE;
- X curp = _strpbrk(t, space);
- X
- X if( anchor && *curp && !IS_WHITE( *curp ) )
- X if( ((anchor == 1)?*curp:_strspn(curp,brk)[-1]) != *brk ) {
- X t++;
- X done = FALSE;
- X }
- X }
- X while( !done );
- X
- X if( (curp == s) && (strchr(brk, *curp) != NIL(char)) ) curp++;
- X }
- X
- Xfound_token:
- X string->tk_str = curp;
- X string->tk_cchar = *curp;
- X *curp = '\0';
- X
- X DB_PRINT( "tok", ("Returning [%s]", s) );
- X DB_RETURN( s );
- X}
- X
- X
- X
- Xstatic int
- X_is_conditional( tg )/*
- X=======================
- X Look at tg and return it's value if it is a conditional identifier
- X otherwise return 0. */
- Xchar *tg;
- X{
- X DB_ENTER( "_is_conditional" );
- X
- X tg++;
- X switch( *tg ) {
- X case 'I': if( !strcmp( tg, "IF" )) DB_RETURN( ST_IF ); break;
- X
- X case 'E':
- X if( !strcmp( tg, "END" )) DB_RETURN( ST_END );
- X else if( !strcmp( tg, "ELSE" )) DB_RETURN( ST_ELSE );
- X break;
- X }
- X
- X DB_RETURN( 0 );
- X}
- X
- X
- X
- Xstatic int
- X_handle_conditional( opcode, tg )/*
- X===================================
- X Perform the necessary processing for .IF conditinal targets.
- X Someday this should be modified to do bracketted expressions ala
- X CPP... sigh */
- Xint opcode;
- XTKSTRPTR tg;
- X{
- X static short action[MAX_COND_DEPTH];
- X char *tok, *lhs, *rhs, *op, *expr;
- X int result;
- X
- X DB_ENTER( "_handle_conditional" );
- X
- X switch( opcode ) {
- X case ST_IF:
- X if( Nest_level+1 == MAX_COND_DEPTH )
- X Fatal( ".IF .ELSE ... .END nesting too deep" );
- X
- X If_expand = TRUE;
- X expr = Expand( Get_token( tg, NIL(char), FALSE ));
- X If_expand = FALSE;
- X lhs = _strspn( expr, " \t" );
- X if( !*lhs ) lhs = NIL(char);
- X
- X if( (op = _strstr( lhs, "==" )) == NIL(char) )
- X op = _strstr( lhs, "!=" );
- X
- X if( op == NIL(char) )
- X result = (lhs != NIL(char));
- X else {
- X op[1] = op[0];
- X if( lhs != op ) {
- X for( tok = op-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
- X tok-- );
- X tok[1] = '\0';
- X }
- X else
- X lhs = NIL(char);
- X
- X op++;
- X rhs = _strspn( op+1, " \t" );
- X if( !*rhs ) rhs = NIL(char);
- X
- X if( (rhs == NIL(char)) || (lhs == NIL(char)) )
- X result = (rhs == lhs) ? TRUE : FALSE;
- X else {
- X tok = rhs + strlen( rhs );
- X for( tok=tok-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
- X tok--);
- X tok[1] = '\0';
- X
- X result = (strcmp( lhs, rhs ) == 0) ? TRUE : FALSE;
- X }
- X
- X if( *op == '!' ) result = !result;
- X }
- X
- X if( expr != NIL(char) ) FREE( expr );
- X Nest_level++;
- X
- X if( result )
- X action[ Nest_level ] = action[ Nest_level-1 ];
- X else
- X action[ Nest_level ] = 1;
- X break;
- X
- X case ST_ELSE:
- X if( Nest_level <= 0 ) Fatal( ".ELSE without .IF" );
- X if( action[ Nest_level-1 ] != 1 )
- X action[ Nest_level ] ^= 0x1; /* flip between 0 and 1 */
- X break;
- X
- X case ST_END:
- X Nest_level--;
- X if( Nest_level < 0 ) Fatal( "Unmatched .END" );
- X break;
- X }
- X
- X DB_RETURN( action[ Nest_level ] );
- X}
- X
- SHAR_EOF
- chmod 0440 getinp.c || echo "restore of getinp.c fails"
- echo "x - extracting function.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > function.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/function.c,v 1.1 90/10/06 12:04:36 dvadura Exp $
- X-- SYNOPSIS -- GNU style functions for dmake.
- X--
- X-- DESCRIPTION
- X-- All GNU stule functions understood by dmake are implemented in this
- X-- file. Currently the only such function is $(mktmp ...) which is
- X-- not part of GNU-make is an extension provided by dmake.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: function.c,v $
- X * Revision 1.1 90/10/06 12:04:36 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#include "extern.h"
- X#include "alloc.h"
- X
- Xstatic char *_exec_mktmp ANSI((char *, char *));
- X
- X
- Xchar *
- XExec_function(buf)/*
- X====================
- X Execute the function given by the value of args.
- X
- X So far mktmp is the only valid function, anything else elicits and error
- X message. It is my hope to support the GNU style functions in this portion
- X of the code at some time in the future. */
- Xchar *buf;
- X{
- X char *fname;
- X char *args = NIL(char);
- X char *mod = NIL(char);
- X char *res = NIL(char);
- X
- X /* This must succeed since the presence of ' ', \t or \n is what
- X * determines if this functions is called in the first place. */
- X fname = _substr(buf, args=_strpbrk(buf," \t\n"));
- X
- X if( (mod = strchr(fname,',')) != NIL(char) ){
- X *mod = '\0';
- X mod++;
- X }
- X
- X switch( *fname ) {
- X case 'm':
- X if( strncmp(fname,"mktmp", 5) == 0 ) res = _exec_mktmp(mod, args);
- X break;
- X }
- X
- X if( res == NIL(char) ) {
- X Warning( "Function '%s' not implemented at this time", fname );
- X res = _strdup("");
- X }
- X
- X return(res);
- X}
- X
- X
- Xstatic char *
- X_exec_mktmp( mod, data )
- Xchar *mod;
- Xchar *data;
- X{
- X register char *p;
- X char *tmpname;
- X FILE *tmpfile;
- X char *name;
- X
- X tmpfile = Start_temp( "", Recipe_cell, Recipe_how, &tmpname );
- X data = Expand(_strspn(data, " \t\n"));
- X name = Recipe_cell ? Recipe_cell->CE_NAME:"makefile text";
- X
- X for(p=strchr(data,'\n'); p; p=strchr(p,'\n')) {
- X char *q = _strspn(++p," \t");
- X strcpy(p,q);
- X }
- X
- X Append_line( data, FALSE, tmpfile, name, FALSE, TRUE );
- X Close_temp( Recipe_how, tmpfile );
- X FREE(data);
- X
- X return( (mod != NIL(char) && *mod) ? Expand(mod) : _strdup(tmpname) );
- X}
- SHAR_EOF
- chmod 0440 function.c || echo "restore of function.c fails"
- echo "x - extracting extern.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > extern.h &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/extern.h,v 1.1 90/10/06 12:04:24 dvadura Exp $
- X-- SYNOPSIS -- external declarations for dmake functions.
- X--
- X-- DESCRIPTION
- X-- ANSI is a macro that allows the proper handling of ANSI style
- X-- function declarations.
- X--
- X-- AUTHOR
- X-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
- X-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
- X--
- X-- COPYRIGHT
- X-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
- X--
- X-- This program is free software; you can redistribute it and/or
- X-- modify it under the terms of the GNU General Public License
- X-- (version 1), as published by the Free Software Foundation, and
- X-- found in the file 'LICENSE' included with this distribution.
- X--
- X-- This program is distributed in the hope that it will be useful,
- X-- but WITHOUT ANY WARRANTY; without even the implied warrant of
- X-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X-- GNU General Public License for more details.
- X--
- X-- You should have received a copy of the GNU General Public License
- X-- along with this program; if not, write to the Free Software
- X-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X--
- X-- LOG
- X-- $Log: extern.h,v $
- X * Revision 1.1 90/10/06 12:04:24 dvadura
- X * dmake Release, Version 3.6
- X *
- X*/
- X
- X#ifndef EXTERN_h
- X#define EXTERN_h
- X
- X#include "vextern.h"
- X#include <stdlib.h>
- X#include <string.h>
- X
- Xextern void Add_dfa ANSI((char *));
- Xextern void Add_fringe ANSI((CELLPTR));
- Xextern void Add_recipe_to_list ANSI((char *, int, int));
- Xextern LINKPTR Add_prerequisite ANSI((HOWPTR, CELLPTR, int));
- Xextern char* Apply_edit ANSI((char *, char *, char *, int, int));
- Xextern void Append_line ANSI((char*, int, FILE*, char*, int, int));
- Xextern char* basename ANSI((char*));
- Xextern void Bind_rules_to_targets ANSI((int));
- Xextern char* Build_path ANSI((char *, char *));
- Xextern void Catch_signals ANSI((void (*)()));
- Xextern void Check_circle ANSI((LINKPTR));
- Xextern void Check_circle_dfa ANSI(());
- Xextern void Clear_prerequisites ANSI((HOWPTR));
- Xextern void Clear_signals ANSI(());
- Xextern void Clean_up_processes ANSI(());
- Xextern FILE* Closefile ANSI(());
- Xextern void Close_temp ANSI((HOWPTR, FILE *));
- Xextern void Create_macro_vars ANSI(());
- Xextern DFAPTR Construct_dfa ANSI((char *));
- Xextern CELLPTR Def_cell ANSI((char *, CELLPTR));
- Xextern HASHPTR Def_macro ANSI((char *, char *, int));
- Xextern STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int));
- Xextern int Do_cmnd ANSI((char *, int, int, CELLPTR, HOWPTR, int,int,int));
- Xextern time_t Do_stat ANSI((char *, char *, char **));
- Xextern time_t Do_time ANSI(());
- Xextern int Do_touch ANSI((char *, char *, char **));
- Xextern void Dump ANSI(());
- Xextern void Dump_recipe ANSI((STRINGPTR));
- Xextern void Epilog ANSI((int));
- Xextern char* Exec_function ANSI((char *));
- Xextern char* Expand ANSI((char *));
- Xextern CELLPTR Explode_cell ANSI((CELLPTR, CELLPTR));
- Xextern HOWPTR Explode_how ANSI((HOWPTR, CELLPTR, int));
- Xextern LINKPTR Explode_prq ANSI((LINKPTR, CELLPTR, int));
- Xextern char* Filename ANSI(());
- Xextern char* Get_current_dir ANSI(());
- Xextern int Get_line ANSI((char *, FILE *));
- Xextern HASHPTR Get_name ANSI((char *, HASHPTR *, int, CELLPTR));
- Xextern char* Get_suffix ANSI((char *));
- Xextern char Get_switch_char ANSI(());
- Xextern char* Get_token ANSI((TKSTRPTR, char *, int));
- Xextern uint16 Hash ANSI((char *,uint32 *));
- Xextern void Handle_result ANSI((int, int, int, CELLPTR));
- Xextern int If_root_path ANSI((char *));
- Xextern CELLPTR Infer_recipe ANSI((CELLPTR, HOWPTR, DFASETPTR, CELLPTR));
- Xextern int Macro_op ANSI((char *));
- Xextern int Make ANSI((CELLPTR, HOWPTR, CELLPTR));
- Xextern void Make_rules ANSI(());
- Xextern void Map_esc ANSI((char *));
- Xextern DFALINKPTR Match_dfa ANSI((char *));
- Xextern char* My_malloc ANSI((unsigned int, char *, int));
- Xextern char* My_calloc ANSI((unsigned int, unsigned int, char *, int));
- Xextern void My_free ANSI((char *, char *, int));
- Xextern void No_ram ANSI(());
- Xextern FILE* Open_temp ANSI((char **, char *));
- Xextern FILE* Openfile ANSI((char *, int));
- Xextern char** Pack_argv ANSI((int, int, char *));
- Xextern void Parse ANSI((FILE *));
- Xextern int Parse_macro ANSI((char *, int));
- Xextern int Parse_rule_def ANSI((int *));
- Xextern void Pop_dir ANSI((int));
- Xextern void Prolog ANSI((int, char **));
- Xextern int Push_dir ANSI((CELLPTR, int));
- Xextern void Quit ANSI(());
- Xextern char* Read_env_string ANSI((char *));
- Xextern void ReadEnvironment ANSI(());
- Xextern void Remove_prq ANSI((CELLPTR));
- Xextern int Rule_op ANSI((char *));
- Xextern int runargv ANSI((CELLPTR, HOWPTR, int, int, int, int, char *));
- Xextern time_t seek_arch ANSI((char*, char*));
- Xextern int Set_dir ANSI((char *));
- Xextern int Set_group_attributes ANSI((char *));
- Xextern void Stat_target ANSI((CELLPTR, int));
- Xextern FILE* Start_temp ANSI((char *, CELLPTR, HOWPTR, char **));
- Xextern int Test_circle ANSI((CELLPTR, int));
- Xextern int touch_arch ANSI((char*, char*));
- Xextern void Unlink_temp_files ANSI((HOWPTR));
- Xextern void Update_time_stamp ANSI((CELLPTR, HOWPTR));
- Xextern void Void_lib_cache ANSI((char *, char *));
- Xextern int Wait_for_child ANSI((int, int));
- Xextern int Write_env_string ANSI((char *, char *));
- X
- Xextern char* _stradd ANSI((char *,char *, int));
- Xextern char* _strapp ANSI((char *,char *));
- Xextern char* _strjoin ANSI((char *,char *,int, int));
- Xextern char* _strdup ANSI((char *));
- Xextern char* _strpbrk ANSI((char *,char *));
- Xextern char* _strspn ANSI((char *,char *));
- Xextern char* _strstr ANSI((char *,char *));
- Xextern char* _substr ANSI((char *,char *));
- X
- X/* Include this last as it invalidates some functions that are defined
- X * externally above and turns them into no-ops. Have to do this after
- X * the extern declarations however. */
- X#include "config.h"
- X
- X#endif
- X
- SHAR_EOF
- chmod 0440 extern.h || echo "restore of extern.h fails"
- echo "x - extracting expand.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > expand.c &&
- X/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/expand.c,v 1.1 90/10/06 12:03:40 dvadura Exp $
- X-- SYNOPSIS -- macro expansion code.
- X--
- X-- DESCRIPTION
- X--
- X-- This routine handles all the necessary junk that deals with macro
- X-- expansion. It understands the following syntax. If a macro is
- X-- not defined it expands to NULL, and {} are synonyms for ().
- X--
- X-- $$ - expands to $
- X-- {{ - expands to {
- X-- }} - expands to }
- X-- $A - expands to whatever the macro A is defined as
- X-- $(AA) - expands to whatever the macro AA is defined as
- SHAR_EOF
- echo "End of part 20"
- echo "File expand.c is continued in part 21"
- echo "21" > s2_seq_.tmp
- exit 0
-
-